"""
@name : io模型
@author : wenyao
@projectname: sanchuanglianxi
"""
# linux 下五种io模型
# 阻塞io
# 非阻塞io
# io复用
# 信号驱动
# 异步io

#阻塞和非阻塞关注的是程序在等待调用结果时的状态
#等待调用结果的过程中 有没有做其他事情

#同步和异步 关注的是消息通信机制
#你是主动去获取这个结果  还是被动的被通知获取这个结果
#主动与被动的关系

#cpu的两种状态： 用户态和内核态
#用户态：运行用户程序
#内核态：运行操作系统的程序，操作硬件

#用户程序通过“系统调用” 或者中断  去陷入内核

#socket网络编程


#1、阻塞io
#数据的两个阶段都被block，整个用户进程被阻塞，直到数据获取完成。

#2、非阻塞io模型
#等待数据阶段：socket非阻塞，用户发起请求之后，立刻就得到结果，不管有没有数据到达，
# 如果没有获取到数据，用户需要不断的发送io请求一直到获取数据才继续执行
#这个过程很消耗资源，占用大量cpu，一般实际应用中很少

#3、io多路复用  （nginx web服务器epoll）
#一个进程或线程能处理多个io请求（减少创建多个线程或进程同步执行的io开销）
#计算机里面没有什么是 加中间层 解决不了的。
#三种：select, poll, epoll
#文件描述符:fd
#用户进程在调用recv()之前，先调用select/poll/epoll, 将socket信息注册到select，当数据到达时
#select被激活，select函数通知用户进程发起read请求。
#通过某种机制它能同时监听多个fd，而这些中任意一个进入就绪状态，selct函数就可以返回。

#select/poll/epoll
#select/poll
#1、当有io就绪，select会遍历所有的fd，来找到就绪fd
#2、每次调用select()，都会把所有的fd_set从用户态拷贝到内核态。
#3、selct所监听的fd_set有限制，一般来说最多只能监听1024个
#4、poll跟select实现类似，但是没有fd监听限制

#epoll  (epoll_create,epoll_ctl,epoll_wait)
#1、每个fd在整个过程中只拷贝一次
#2、效率提升不是采用轮询，而是回调
#3、没有并发连接的限制


#4、信号驱动io
#5、异步io
#整个过程都是非阻塞，并且数据准备好之后，通知程序去获取。

# class A:
#     def func1():
#         print("this is func1")
#
# a = A()
# #a.func1()  -->A.func1(a)
# A.func1()

# #抽象基类
# from abc import ABC, abstractmethod
#
# class A(ABC):
#     @abstractmethod
#     def func1(self):
#         pass
#
# class B(A):
#     def func1(self):
#         print("this is func1")
#
# b = B()
# a = A()
# 1.创建角色：姓名、性别
# 2.创建房间：
# 角色可加入房间
# 房间内的人可互打
# 房间上限3人
# 3.战斗：
# 装备、默认血量、被正常攻击掉血与有装备掉血不同


# import random
# class Role(object):
# 	def __init__(self,name,sex,blood=100):
# 		self.name = name
# 		self.sex = sex
# 		self.blood = blood
# 		self.room = None
# 	def attach(self,other):
# 		fight = {10:"物理攻击",20:"魔法攻击"}
# 		if self == other:
# 			print("不能攻击自己")
# 		else:
# 			if self.room and self.room == other.room:
# 				if self.blood <= 0:
# 					print("您的血量低于0，不能进行攻击")
# 				else:
# 					if random.choice([0,1]) == 0:
# 						lost_blood = random.choice([10,20])
# 						print(f"{other.name}没有装备")
# 					else:
# 						lost_blood = random.choice([10,20])
# 						print(f"{other.name}使用了装备")
# 					other.blood = other.blood - lost_blood
# 					print(f"{self.name}使用{fight[lost_blood]}攻击了{other.name}{lost_blood}点血量，当前血量{other.blood}")
# 					if other.blood <= 0:
# 						print(f"{other.name}已阵亡，不能再进行攻击")
# 						exit()
# 			else:
# 				print("不在同一个房间不能攻击")
# class Room(object):
# #	MAX = 2
# 	def __init__(self,name):
# 		self.name = name
# 		self.member_list = []
# 	def add_member(self,role):
# 		if role.room == None:
# 			if len(self.member_list) < 2:
# 				self.member_list.append(role)
# 				role.room = self
# 				print(f"{role.name}成功加入{self.name}房间")
# 		else:
# 			print(f"{role.name}已加入{role.room.name}房间")
# print('''################
# 1.创建角色
# 2.创建房间
# 3.加入房间
# 4.开始战斗
# 5.退出
# ################''')
# roles = dict()
# rooms = dict()
# while True:
# 	enter_number = input("请输入您的操作：\n")
# 	if enter_number.isdigit():
# 		enter_number = int(enter_number)
# 		if 1 <= enter_number <= 5:
# 			if enter_number == 1:
# 				name,sex = input("请输入角色的姓名与性别，空格分隔：\n").split()
# 				roles[name] = Role(name,sex)
# 			elif enter_number == 2:
# 				room = input("请输入房间的名字：\n")
# 				rooms[room] = Room(room)
# 			elif enter_number == 3:
# 				print(f"当前角色有{roles.keys()}，当前房间有{rooms.keys()}")
# 				role_name,room_name = input("请输入您要加入的角色和房间名，空格分隔:\n").split()
# 				rooms[room_name].add_member(roles[role_name])
# 			elif enter_number == 4:
# 				while True:
# 					enter = random.choice([0,1])
# 					if enter == 0:
# 						rooms[room_name].member_list[0].attach(rooms[room_name].member_list[1])
# 					else:
# 						rooms[room_name].member_list[1].attach(rooms[room_name].member_list[0])
# 		else:
# 			print("输入错误！请输入1-5选择操作！")
# 	else:
# 		print("输入有误！请重新输入！")

###编写一个shellException异常，返回状态码及错误详情
###编写run_command函数，实现运行shell命令功能，返回stdout
##编写上下文管理器，处理指定类型的错误码，如错误码为1则忽略次错误

# from subprocess import Popen, PIPE, STDOUT
# import os
#
#
# def run_command(command):
#     currentPath = os.path.dirname(os.path.realpath(__file__))
#     p = Popen(command, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True, cwd=currentPath)
#     output, errors = p.communicate()
#     resultcode=p.returncode   ##得到执行命令的状态码
#     context=bytes(errors).decode("utf-8")    ###得到错误详情
#     result=bytes(output).decode("utf-8")    ###得到执行的正确结果
#     if resultcode !=0:     ###如果有错误，则抛出自定义异常
#         raise shellException(resultcode,context)
#     return result   ###返回执行命令的结果
#
# ###shellException异常
# class shellException(Exception):
#     def __init__(self,code,content):
#         self.code=code
#         self.content=content
#     def get_error_info(self):
#         return [self.code,self.content]
#
# ###上下文管理器
# class shellContext():
#     def __init__(self,command):
#         self.command=command
#
#     def __enter__(self):
#         return self
#
#     def run_command(self):
#         self.result=run_command(self.command)
#         print("执行结果为:\n",self.result)
#
#     def __exit__(self, exc_type, exc_val, exc_tb):
#         print(exc_type)
#         if exc_type:     ##捕捉到异常
#             print("已经捕捉到异常")
#             if exc_val.code == 1:
#                 print("错误详情:",exc_val.content)
#                 return True
#             return False
# command=input("请输入你的操作:")
# with shellContext(command) as f:
#     f.run_command()
#
# print("shell context end....")

#前端  网页
#自己想一下  学习平台  美妆平台  动漫播放平台
#Flask 框架
#CMDB
# print(2+"5")